package com.front.web.hotel;

import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.utils.*;
import com.bootdo.haojiangboutils.MapBuild;
import com.bootdo.hotel.domain.*;
import com.bootdo.hotel.service.HotelRoomMoneyCodeService;
import com.bootdo.lvyou.domain.LvyouCity;
import com.bootdo.lvyou.domain.LvyouScenicSpot;
import com.bootdo.lvyou.service.LvyouScenicSpotService;
import com.bootdo.websocket.WebSocketServer;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

@RequestMapping("/f/hotelorder/v1/")
@RestController
public class HotelOrderControllerV1 extends  HotelSupperController{


    @RequestMapping("create_order")
    public R createOrder(
            @RequestParam("hotelId") Long hotelId,
            @RequestParam("codeId") Long codeId,
            @RequestParam("startTime")String startTime,
            @RequestParam("endTime")String endTime,
            @RequestParam("roomNum")Integer roomNum,
            @RequestParam("memberMobile")String memberMobile,
            @RequestParam("memberName")String memberName,
            HttpServletRequest request,HttpServletResponse response) throws ParseException {
        if(roomNum <= 0){
            return R.error("房间数不能为0");
        }
        HotelOrder hotelOrder = new HotelOrder();
        HotelRoomMoneyCode hotelRoomMoneyCode =   hotelRoomMoneyCodeService.get(codeId);

        hotelOrder.setRoomTypeId(hotelRoomMoneyCode.getRoomTypeId());
        hotelOrder.setRoomTypeName(hotelRoomMoneyCode.getRoomTypeName());
        hotelOrder.setMoneyCodeId(codeId);
        hotelOrder.setMoneyCodeName(hotelRoomMoneyCode.getName());

        hotelOrder.setInDate(DateUtils.pasre(startTime,DateUtils.DATE_PATTERN));
        hotelOrder.setInTime(DateUtils.getCustomTime(14));
        hotelOrder.setOutDate(DateUtils.pasre(endTime,DateUtils.DATE_PATTERN));
        Date outDate =  DateUtils.getCustomTimebyDay(hotelOrder.getOutDate(),14,0,0,0);
        hotelOrder.setOutTime(outDate);
        if(hotelOrder.getInTime().after(hotelOrder.getOutTime())){
            return R.error("退房时间不能小于当前时间");
        }

        LvyouScenicSpot lvyouScenicSpot  =  lvyouScenicSpotService.get(hotelId);


        List<Date> dateList =  DateUtils
                .getStartTimeAndEndTimeEveryDay(
                        hotelOrder.getInDate(),
                        hotelOrder.getOutDate());
        List<String> noStockList = new LinkedList<>();
        List<HotelRoom> hotelRooms =   hotelRoomService.list(MapBuild.getInstand()
                .setKV("hotelId",hotelId)
                .setKV("typeId",hotelRoomMoneyCode.getRoomTypeId()));
        List<HotelRoom> okInRoom =   getOkRoonList(dateList,hotelRooms,roomNum);
        if(okInRoom.size() < roomNum){
            return R.error("可预订的房量不足");
        }
        //设置每日价格
        AtomicReference<Double> totalMoney = new AtomicReference<>(0d);
        List<String> everyDayMoeny = new ArrayList<>();
        for(int d = 0 ; d < dateList.size(); d++){
            Date item = dateList.get(d);
            String itemDay = DateUtils.format(item);
            HotelEveryDayMoney hotelEveryDayMoney =  hotelEveryDayMoneyService.getByCodeIdAndDate(hotelOrder.getMoneyCodeId(), itemDay);
            if(null == hotelEveryDayMoney){
                noStockList.add(itemDay+"没有设置房价");
                break;
            }
            if(d < (dateList.size() -1)){
                everyDayMoeny.add(hotelEveryDayMoney.getMoney().toString());
                totalMoney.updateAndGet(v -> new Double((double) (v + hotelEveryDayMoney.getMoney())));
            }
        }
        if(noStockList.size() > 0){
            return R.error(Arrays.toString(noStockList.toArray()));
        }
        hotelOrder.setMemberName(memberName);
        hotelOrder.setMemberMobile(memberMobile);
        hotelOrder.setRoomIdList(getRoomIdList(okInRoom));
        hotelOrder.setRoomName(getRoomNameList(okInRoom));
        hotelOrder.setRoomNumber(roomNum);
        hotelOrder.setRoomTotalNum(roomNum);
        hotelOrder.setMemberLevel("WX");
        hotelOrder.setHotelMobile(lvyouScenicSpot.getHotelMobile());
        hotelOrder.setDayNum(DateUtils.caculateTotalTime(DateUtils.format(hotelOrder.getInDate()),DateUtils.format(hotelOrder.getOutDate()))-1);
        hotelOrder.setEveryMoney(Arrays.toString(everyDayMoeny.toArray()));
        hotelOrder.setPayMoney(0d);
        hotelOrder.setTotalMoney(totalMoney.get() *  hotelOrder.getRoomNumber());
        hotelOrder.setUserId(hotelRoomMoneyCode.getUserId());
        hotelOrder.setUserName(hotelRoomMoneyCode.getUserName());
        hotelOrder.setHotelId(hotelRoomMoneyCode.getHotelId());
        hotelOrder.setHotelName(hotelRoomMoneyCode.getHotelName());
        //入住
        hotelOrder.setStatus(0);
        hotelOrder.setOrderNo(SnowflakeIdWorker.getOrderNo("W"));
        hotelOrder.setOrderSrc("WX");
        hotelOrder.setHotelRooms(okInRoom);
        redisUtil.set("HOTEL_CREATE_ORDER"+hotelOrder.getOrderNo(),hotelOrder,300);
       /* */
        return R.ok().put("i",hotelOrder).put("key",hotelOrder.getOrderNo());
    }


    @RequestMapping("create_pay_order")
    public R createPayOrder(@RequestParam("key")String key, HttpServletRequest request){
        if(null ==  redisUtil.get("HOTEL_CREATE_ORDER"+key)){
            return R.ok("操作超时，请重新下单");
        }
        HotelOrder hotelOrder = (HotelOrder) redisUtil.get("HOTEL_CREATE_ORDER"+key);

        String memberName =  request.getParameter("memberName");
        String memberMobile = request.getParameter("memberMobile");
        String goHotelTime = request.getParameter("goHotelTime");
        if(StringUtils.isNotEmpty(memberName)){
            hotelOrder.setMemberName(memberName);
        }

        if(StringUtils.isNotEmpty(goHotelTime)){
            hotelOrder.setGoHotelTime(goHotelTime);
        }

        if(StringUtils.isNotEmpty(memberMobile)){
            hotelOrder.setMemberMobile(memberMobile);
        }

        List<Date> dateList =  DateUtils
                .getStartTimeAndEndTimeEveryDay(
                        hotelOrder.getInDate(),
                        hotelOrder.getOutDate());
        List<HotelRoom> okInRoom =   getOkRoonList(dateList,hotelOrder.getHotelRooms(),hotelOrder.getRoomNumber());
        if(okInRoom.size() < hotelOrder.getRoomNumber()){
            return R.error("可预订的房量不足");
        }
        try {
            int z =  hotelOrderService.saveOrderAndDayStatus(hotelOrder);
            try {
                if(null != hotelOrder.getUserId()){
                    WebSocketServer webSocketServer =  WebSocketServer.SOCKER_MAPING.get(hotelOrder.getUserId());
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type",10);
                    jsonObject.put("msg","酒店预订:【"+hotelOrder.getRoomName()+"】有新订单,请及时处理");
                    jsonObject.put("orderNo",hotelOrder.getOrderNo());
                    webSocketServer.sendMessage(jsonObject.toJSONString());
                }
            }catch (Exception e){
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.error(e.getMessage());
        }
        return R.ok("预定成功");
    }


    /**
     * /f/hotelorder/v1/get_order_list
     * @param memberMobile
     * @param offset
     * @param limit
     * @param request
     * @return
     */
    @RequestMapping("get_order_list")
    public R getOrderList(@RequestParam("memberMobile") String memberMobile,
                          @RequestParam("offset") Integer offset,
                          @RequestParam("limit") Integer limit,
                          HttpServletRequest request){
        Map query = MapBuild.getInstand()
                .setKV("offset",offset*limit)
                .setKV("limit",limit)
                .setKV("memberMobile",memberMobile);

        if(null != offset){
            //总记录数
            int rows= hotelOrderService.count(query);
            int pageSum=(rows-1)/limit+1;
            if(offset > pageSum-1){
                return R.error("没有更多了");
            }
        }
       List<HotelOrder> hotelOrders =  hotelOrderService.list(
                query
        );
        return R.ok().put("l",hotelOrders);
    }


    /**
     *
     * 得到订单详情
     * /f/hotelorder/v1/get_order_detail
     * @return
     */
    @RequestMapping("get_order_detail")
    public R getOrderDetail(   @RequestParam("id") Long id,
                          HttpServletRequest request){
        HotelOrder hotelOrder =   hotelOrderService.get(id);
        return R.ok().put("i",hotelOrder);
    }

    /**
     *
     * 得到订单详情
     * /f/hotelorder/v1/get_order_by_inroom
     * @return
     */
    @RequestMapping("get_order_by_inroom")
    public R getOrderByInroom(   @RequestParam("mobile") String mobile,
                               HttpServletRequest request){
       HotelOrder hotelOrder =  hotelOrderService.getByMobileByInRoom(mobile);
       if(null == hotelOrder || hotelOrder.getRoomId() == null){
           return R.error("暂无入住信息");
       }
       HotelRoom  hotelRoom  =   hotelRoomService.get(hotelOrder.getRoomId());
       hotelOrder.setRoomName(hotelRoom.getName());
        return R.ok().put("i",hotelOrder);
    }




    /**
     * /f/hotelorder/v1/out_room
     * 退房
     */
    @ResponseBody
    @PostMapping("/out_room")
    public R outRoom( @RequestParam("id") Long id ,HttpServletRequest request){
        if(null == id || id <= 0){
            return R.error("无效");
        }
        //退房
        HotelOrder hotelOrder = 	hotelOrderService.get(id);
        if(null == hotelOrder){
            return R.error("无效");
        }
        String nowRoomId =  request.getParameter("nowRoomId");
        if(StringUtils.isNotEmpty(nowRoomId)){

            //目前多房预订只能通过微信 所以一个if就够了
            if(hotelOrder.getOrderSrc().equals("WX")){
                if(hotelOrder.getRoomNumber() > 1){
                    hotelOrder.setRoomNumber(hotelOrder.getRoomNumber() - 1);
                    hotelOrder.setRoomId(Long.parseLong(nowRoomId));
                    hotelOrder.setFlag("DUO");
                    hotelOrder.setStatus(0 - hotelOrder.getStatus());
                }else{
                    hotelOrder.setRoomNumber(hotelOrder.getRoomNumber() - 1);
                    hotelOrder.setRoomId(Long.parseLong(nowRoomId));
                    hotelOrder.setFlag("DUO");
                    hotelOrder.setStatus(2);
                }
            }else if(hotelOrder.getOrderSrc().equals("HOTEL")){
                if(hotelOrder.getRoomNumber() > 1){
                    hotelOrder.setRoomNumber(hotelOrder.getRoomNumber() - 1);
                    hotelOrder.setRoomId(Long.parseLong(nowRoomId));
                    hotelOrder.setFlag("DUO");
                    hotelOrder.setStatus(0 - hotelOrder.getStatus());
                }else{
                    hotelOrder.setRoomNumber(hotelOrder.getRoomNumber() - 1);
                    hotelOrder.setRoomId(Long.parseLong(nowRoomId));
                    hotelOrder.setStatus(2);
                }
            }
        }else{
            hotelOrder.setStatus(2);
        }
        try {
            hotelOrderService.saveOrderAndDayStatus(hotelOrder);
            return R.ok("退房成功");
        }catch (Exception e){
            e.printStackTrace();
            return R.error(e.getMessage());
        }
    }




    /**
     *
     * 得到订单详情
     * /f/hotelorder/v1/get_order_by_roomId
     * @return
     */
    @RequestMapping("get_order_by_roomId")
    public R getOrderByInroom(   @RequestParam("roomId") Long  roomId,
                                 HttpServletRequest request){
        HotelRoom hotelRoom = hotelRoomService.get(roomId);
        if(null == hotelRoom){
            return R.error("无效二维码");
        }
        HotelOrder hotelOrder =  new HotelOrder();
        hotelOrder.setRoomId(hotelRoom.getId());
        hotelOrder.setRoomName(hotelRoom.getName());
        hotelOrder.setRoomTypeId(hotelRoom.getTypeId());
        hotelOrder.setRoomTypeName(hotelRoom.getTypeName());
        hotelOrder.setHotelId(hotelRoom.getHotelId());
        hotelOrder.setHotelName(hotelRoom.getHotelName());
        return R.ok().put("i",hotelOrder);
    }



    String getRoomIdList(List<HotelRoom> hotelRooms){
        StringBuilder stringBuilder = new StringBuilder();
        for(HotelRoom item : hotelRooms){
            stringBuilder.append(item.getId()).append(",");
        }
        return stringBuilder.toString();
    }
    String getRoomNameList(List<HotelRoom> hotelRooms){
        StringBuilder stringBuilder = new StringBuilder();
        for(HotelRoom item : hotelRooms){
            stringBuilder.append(item.getName()).append(",");
        }
        return stringBuilder.toString();
    }


    List<HotelRoom>   getOkRoonList(List<Date> dateList,List<HotelRoom> hotelRooms,Integer roomNum){
        List<HotelRoom> okInRoom = new ArrayList<>();
        //得到酒店该房型的所有房间
        for(HotelRoom hotelRoom : hotelRooms){
            boolean isOk = true;
            for(Date date : dateList){
                String itemDay = DateUtils.format(date);
                HotelRoomDayStatus hotelRoomDayStatus =  hotelRoomDayStatusService.getByRoomIdAndDay(hotelRoom.getId(),itemDay);
                if(null != hotelRoomDayStatus){
                    int sta  = hotelRoomDayStatus.getStatus().intValue();
                    //3 在住 5是被预订 4是维修
                    if(sta == 3 || sta == 5 || sta == 4){
                        isOk = false;
                        break;
                    }
                }
            }
            if(isOk){
                //如果该房间可以预订 而且可预订房间数量 等于被预订数量 就返回
                okInRoom.add(hotelRoom);
                if(okInRoom.size() == roomNum){
                    break;
                }
            }
        }
        return okInRoom;
    }

}
